package com.wiwf.model.security.service.impl;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wiwf.model.bean.SysUserVoto;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;

import com.wiwf.model.security.service.SysTokenService;

/**
 * @author kehui
 */
@Service
public class SysTokenServiceImpl implements SysTokenService {

	@Resource
	private HttpServletResponse response;
	@Resource
	private HttpServletRequest request;

	@Resource
	private RedisTemplate<String, SysUserVoto> redisTemplate;
	
	@Value("${base.security.tokenkey:token}")
	private String tokenKey;

	@Value("${base.security.tokentime:31200}")
	private Integer tokenTime;



	@Override
	public String createToken() {
		String token = UUID.randomUUID().toString();
		return getTagString(token);
	}

	@Override
	public Boolean addTokenUser(String key, SysUserVoto val) {
		// token 写入 cookie
		Cookie cookie = new Cookie(tokenKey, key);
		cookie.setPath("/");
		response.addCookie(cookie);
		
		// data 写入 redis
		try {
			redisTemplate.opsForValue().set(key, val, tokenTime, TimeUnit.SECONDS);
		} finally {
			SysTokenService.SYS_USERS.put(key, val);
		}

		return true;
	}

	@Override
	public Boolean updateTokenUser(String key, SysUserVoto val) {
		delTokenUser();
		addTokenUser(key, val);
		return true;
	}

	@Override
	public SysUserVoto getTokenUser() {
		String token = getToken();
		SysUserVoto user = redisTemplate.opsForValue().get(token);
		addTokenUser(token, user);
		return user;
	}

	@Override
	public SysUserVoto getTokenUser(String token) {
		try {
			return redisTemplate.opsForValue().get(token);
		} catch (Exception e) {
			return SysTokenService.SYS_USERS.get(token);
		}
	}

	@Override
	public Boolean delTokenUser(){
		try {
			redisTemplate.delete(getToken());
		} finally {
			SysTokenService.SYS_USERS.remove(getToken());
		}
		return true;
	}

	@Override
	public Boolean updateTokenUserExpire(String key, int timeSeconds) {
		try {
			redisTemplate.expire(key, timeSeconds, TimeUnit.SECONDS);
		} catch (Exception e) {
			return true;
		}
		return true;
	}

	@Override
	public String getToken() {
		try {
			Cookie[] cookies = request.getCookies();
			if(cookies == null || cookies.length == 0){
				return request.getHeader(tokenKey);
			}
			for (Cookie cookie : cookies) {
				if(cookie.getName().equals(tokenKey)) {
					return cookie.getValue();
				}
			}
		} catch (Exception e) {
			return null;
		}
		return request.getHeader(tokenKey);
	}

	String getTagString(String tag) {
		try {
			byte md5[] = MessageDigest.getInstance("md5").digest(tag.getBytes());

			return Base64Utils.encodeToString(Base64Utils.encode(md5));
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}
	}

}
